--- src/xfpm-backlight-helper.c.orig	2014-12-01 11:33:52 UTC
+++ src/xfpm-backlight-helper.c
@@ -19,7 +19,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include "config.h"
+#endif
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -36,6 +38,10 @@
 #include <string.h>
 #endif
 #include <stdio.h>
+#include <stdlib.h>
+#if defined(BACKEND_TYPE_FREEBSD)
+#include <sys/sysctl.h>
+#endif
 
 #define EXIT_CODE_SUCCESS		0
 #define EXIT_CODE_FAILED		1
@@ -43,11 +49,326 @@
 #define EXIT_CODE_INVALID_USER		4
 #define EXIT_CODE_NO_BRIGHTNESS_SWITCH	5
 
+#if !defined(BACKEND_TYPE_FREEBSD)
 #define BACKLIGHT_SYSFS_LOCATION	"/sys/class/backlight"
 #define BRIGHTNESS_SWITCH_LOCATION	"/sys/module/video/parameters/brightness_switch_enabled"
+#endif
+
+
+#if defined(BACKEND_TYPE_FREEBSD)
+gboolean
+acpi_video_is_enabled (gchar *device)
+{
+	return (backlight_helper_get_switch (device) == 1) ? TRUE : FALSE;
+}
+
+gint
+backlight_helper_get_switch (gchar *device)
+{
+	size_t size;
+	gint buf, res = -1;
+	gchar *name;
+
+	name = g_strdup_printf ("hw.acpi.video.%s.active", device);
+	size = sizeof (buf);
+
+	if (sysctlbyname (name, &buf, &size, NULL, 0) == 0)
+		res = buf;
+
+	g_free (name);
+	return res;
+}
+
+gint
+backlight_helper_get_brightness (gchar *device)
+{
+	size_t size;
+	gint buf, res = -1;
+	gchar *name;
+
+	name = g_strdup_printf ("hw.acpi.video.%s.brightness", device);
+	size = sizeof (buf);
+
+	if (sysctlbyname (name, &buf, &size, NULL, 0) == 0)
+		res = buf;
+
+	g_free (name);
+	return res;
+}
+
+gint
+int_cmp (gconstpointer a, gconstpointer b)
+{
+	return (gint) a < (gint) b ? -1 : ((gint) a == (gint) b ? 0 : 1);
+}
+
+GList *
+backlight_helper_get_levels (gchar *device)
+{
+	size_t size;
+	gint *levels;
+	gint nlevels, i;
+	GList *list = NULL, *item;
+	gchar *name;
+
+	name = g_strdup_printf ("hw.acpi.video.%s.levels", device);
+
+	/* allocate memory */
+	sysctlbyname (name, NULL, &size, NULL, 0);
+	levels = (int *) malloc (size);
+
+	if (sysctlbyname (name, levels, &size, NULL, 0) == 0) {
+		nlevels = size / sizeof (gint);
+
+		for (i = 0; i < nlevels; i++) {
+			/* no duplicate item */
+			item = g_list_find (list, GINT_TO_POINTER (levels[i]));
+			if (item == NULL)
+				list = g_list_append (list,
+						      GINT_TO_POINTER (levels[i]));
+		}
+	}
+
+	g_free (levels);
+	g_free (name);
+
+	if (list != NULL)
+		list = g_list_sort (list, int_cmp);
+
+	return list;
+}
 
+gboolean
+backlight_helper_set_switch (gchar *device, gint value)
+{
+	size_t size;
+	gint buf, old_buf;
+	gchar *name;
+	gint res = -1;
+	gboolean result = FALSE;
+
+	name = g_strdup_printf ("hw.acpi.video.%s.active", device);
+
+	res = backlight_helper_get_switch (device);
+	if (res != -1) {
+		old_buf = res;
+		size = sizeof (buf);
+
+		/* we change value and check if it's really different */
+		if (sysctlbyname (name, &buf, &size, &value, sizeof (value)) == 0) {
+			res = backlight_helper_get_switch (device);
+			if (res != -1 && res != old_buf)
+				result = TRUE;
+		}
+	}
+	g_free (name);
+	
+	return result;
+}
+
+gboolean
+backlight_helper_set_brightness (gchar *device, gint value)
+{
+	size_t size;
+	gint buf, old_buf;
+	gchar *name;
+	gint res = -1;
+	gboolean result = FALSE;
+
+	name = g_strdup_printf ("hw.acpi.video.%s.brightness", device);
+
+	res = backlight_helper_get_brightness (device);
+	if (res != -1) {
+		old_buf = res;
+		size = sizeof (buf);
+
+		/* we change value, and check if it's really different */
+		if (sysctlbyname (name, &buf, &size, &value, sizeof (value)) == 0) {
+			res = backlight_helper_get_brightness (device);
+			if (res != -1 && res != old_buf)
+				result = TRUE;
+		}
+	}
+
+	g_free (name);
+
+	return result;
+}
 
 /*
+ * Find device which supports backlight brightness
+ */
+static gchar *
+backlight_helper_get_device (void)
+{
+	/* 'tv' device is also available */
+	gchar *types[] = { "lcd", "crt", "out", "ext", NULL };
+	gchar *device = NULL;
+	gint i;
+
+	device = (gchar *) g_malloc (sizeof (gchar));
+
+	for (i = 0; types[i] != NULL; i++) {
+		g_snprintf (device, 5, "%s0", types[i]);
+
+		/* stop, when first device is found */
+		if (acpi_video_is_enabled (device))
+			break;
+	}
+
+	return device;
+}
+
+/*
+ * Backlight helper main function
+ */
+gint
+main (gint argc, gchar *argv[])
+{
+	GOptionContext *context;
+	gint uid;
+	gint euid;
+	guint retval = 0;
+	const gchar *pkexec_uid_str;
+	gint ret = -1;
+	gint set_brightness = -1;
+	gboolean get_brightness = FALSE;
+	gboolean get_max_brightness = FALSE;
+	gint set_brightness_switch = -1;
+	gboolean get_brightness_switch = FALSE;
+	gchar *device = NULL;
+	GList *list = NULL;
+
+	const GOptionEntry options[] = {
+		{ "set-brightness", '\0', 0, G_OPTION_ARG_INT, &set_brightness,
+		   /* command line argument */
+		  "Set the current brightness", NULL },
+		{ "get-brightness", '\0', 0, G_OPTION_ARG_NONE, &get_brightness,
+		   /* command line argument */
+		  "Get the current brightness", NULL },
+		{ "get-max-brightness", '\0', 0, G_OPTION_ARG_NONE, &get_max_brightness,
+		   /* command line argument */
+		  "Get the number of brightness levels supported", NULL },
+		{ "set-brightness-switch", '\0', 0, G_OPTION_ARG_INT, &set_brightness_switch,
+                  /* command line argument */
+		  "Enable or disable ACPI video brightness switch handling", NULL },
+		{ "get-brightness-switch", '\0', 0, G_OPTION_ARG_NONE, &get_brightness_switch,
+                  /* command line argument */
+		  "Get the current setting of the ACPI video brightness switch handling", NULL },
+		{ NULL }
+	};
+
+	context = g_option_context_new (NULL);
+	g_option_context_set_summary (context, "XFCE Power Manager Backlight Helper");
+	g_option_context_add_main_entries (context, options, NULL);
+	g_option_context_parse (context, &argc, &argv, NULL);
+	g_option_context_free (context);
+
+	/* no input */
+	if (set_brightness == -1 && !get_brightness && !get_max_brightness &&
+	    set_brightness_switch == -1 && !get_brightness_switch) {
+		g_print ("No valid option was specifiedi\n");
+		retval = EXIT_CODE_ARGUMENTS_INVALID;
+		goto out;
+	}
+
+	/* find backlight device */
+	device = backlight_helper_get_device ();
+
+	if (device != NULL) {
+		/* get the current setting of the ACPI video brightness switch handling */
+		if (get_brightness_switch) {
+			ret = backlight_helper_get_switch (device);
+			/* just print result to stdout */
+			g_print ("%d", ret);
+			if (ret == -1)
+				retval = EXIT_CODE_FAILED;
+			else
+				retval = EXIT_CODE_SUCCESS;
+			goto out;
+		}
+
+		/* get current brightness level */
+		if (get_brightness) {
+			ret = backlight_helper_get_brightness (device);
+			/* just print result to stdout */
+			g_print ("%d", ret);
+			if (ret == -1)
+				retval = EXIT_CODE_FAILED;
+			else
+				retval = EXIT_CODE_SUCCESS;
+			goto out;
+		}
+
+		/* get maximum brightness level */
+		if (get_max_brightness) {
+			list = backlight_helper_get_levels (device);
+			if (list != NULL) {
+				/* just print result to stdout */
+				g_print ("%d", (gint) g_list_last (list)->data);
+				g_list_free (list);
+				retval = EXIT_CODE_SUCCESS;
+				goto out;
+			}
+			else {
+				g_print ("Could not get the maximum value of the backlight\n");
+				retval = EXIT_CODE_FAILED;
+				goto out;
+			}
+		}
+
+		/* get calling process */
+		uid = getuid ();
+		euid = geteuid ();
+		if (uid != 0 || euid != 0) {
+			g_print ("This program can only be used by the root user\n");
+			retval = EXIT_CODE_ARGUMENTS_INVALID;
+			goto out;
+		}
+
+		/* check we're not being spoofed */
+		pkexec_uid_str = g_getenv ("PKEXEC_UID");
+		if (pkexec_uid_str == NULL) {
+			g_print ("This program must only be run through pkexec\n");
+			retval = EXIT_CODE_INVALID_USER;
+			goto out;
+		}
+
+		/* set the brightness level */
+		if (set_brightness != -1) {
+			if (backlight_helper_set_brightness (device, set_brightness)) {
+				retval = EXIT_CODE_SUCCESS;
+				goto out;
+			}
+			else {
+				g_print ("Could not set the value of the backlight\n");
+				retval = EXIT_CODE_FAILED;
+				goto out;
+			}
+		}
+
+		/* enable or disable ACPI video brightness switch handling */
+		if (set_brightness_switch != -1) {
+			if (backlight_helper_set_switch (device, set_brightness_switch)) {
+				retval = EXIT_CODE_SUCCESS;
+				goto out;
+			}
+			else {
+				g_print ("Could not set the value of the brightness switch\n");
+				retval = EXIT_CODE_FAILED;
+				goto out;
+			}
+		}
+	}
+	else {
+		retval = ret;
+		goto out;
+	}
+out:
+	return retval;
+}
+#else
+/*
  * Find best backlight using an ordered interface list
  */
 static gchar *
@@ -322,4 +643,4 @@ out:
 	g_free (contents);
 	return retval;
 }
-
+#endif
